package com.y3k.service;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;

import com.y3k.mail.MailConfiguration;
import com.y3k.model.Configuration;
import com.y3k.model.CustomerInfo;
import com.y3k.model.CustomerInfoMessagesHome;
import com.y3k.model.Datasource;
import com.y3k.model.LicenseLoader;
import com.y3k.model.Notification;
import com.y3k.utils.ConfigurationUtil;

public class ConfigurationService {

	public static final Logger log = Logger.getLogger(ConfigurationService.class);

	public ConfigurationService() {

	}

	public void setApplicationConfiguration(String path, Configuration configuration, List<Datasource> datasources, List<Notification> notifications,
			MailConfiguration mailConfiguration) throws ServiceException {
		ConfigurationUtil.DATASOURCES = datasources;

		ConfigurationUtil.PATH = path;
		ConfigurationUtil.CONFIGURATION = configuration;
		ConfigurationUtil.MAIL = mailConfiguration;
		
		for (Iterator<Datasource> it = ConfigurationUtil.DATASOURCES.iterator(); it.hasNext();) {
			log.info("Registrando Datasource [" + it.next().getName() + "]");
		}

		log.info("Registrando notificadores [" + notifications.size() + "]");
		ConfigurationUtil.NOTIFICATIONS = notifications;
	}

	// Controla que la licencia no haya expirado, sea valida, etc
	public CustomerInfo validate() throws ServiceException {
		LicenseLoader license = LicenseLoader.getInstance();

		CustomerInfo info = new CustomerInfo();
		info.setValid(license.isValid()); // Verifica que el archivo de
		// licencia no haya sido adulterado
		info.setTrial(license.isTrial());
		info.setName(license.getCustomer().getName());
		info.setDays(license.getRemainingDays(license.getCustomer().getExpirationDays(), info)); // Modifica
		// el
		// contenido
		// de
		// info

		// Checkear que el archivo de licencia no haya sido adulterado y este
		// firmado con el certificado orignal
		if (info.isValid()) {

			// Si info.result es diferente de cero, entonces dejar el valor
			// seteado por license.getRemainingDays
			if (info.getResult() != 0) {
				// result y message siguen valiendo lo seteado por la invocacion
				// a license.getRemainingDays que detecto
				// una modificacion de fechas del sistema.
			} else {
				if (info.isTrial()) {
					// Si ya se vencieron los dias del trial, indicarlo
					if (info.getDays() <= 0) {
						info.setResult(CustomerInfoMessagesHome.TRIAL_IS_OVER);
						info.setMessage("Trial is over.\nTo register please contact to Y3K-it.");
					} else {
						info.setResult(CustomerInfoMessagesHome.TRIAL);
						info.setMessage("You are using a trial of Dashboard.\nTo register please contact to Y3K-it.");
					}
				} else {
					// Si ya vencieron los dias de la licencia (aunque no sea
					// trial), indicarlo
					if (info.getDays() <= 0) {
						info.setResult(CustomerInfoMessagesHome.LICENSE_IS_OVER);
						info.setMessage("License is over.\nTo register please contact to Y3K-it.");
					} else {
						info.setResult(CustomerInfoMessagesHome.OK); // No es
						// trial
						// y la
						// licencia
						// no
						// esta
						// vencida
					}
				}
			}
		} else {
			info.setResult(CustomerInfoMessagesHome.INVALID_LICENSE_FILE);
			info.setMessage("The license file is invalid.\nPlease contact to Y3K-it to obtain a valid license.");
		}
		return info;
	}

	// Toma el archivo control.dat ya existente y lo modifica con la nueva fecha
	// de registracion
	public void generateLicenseControlFile() throws ServiceException {
		URL controlUrl = Thread.currentThread().getContextClassLoader().getResource("resources/license/control.dat");
		try {
			// Fecha de registracion de la aplicacion
			long licenseDate = System.currentTimeMillis();

			/*
			 * //TODO reemplazar los %20 en windows por espacio String control =
			 * controlUrl.getPath(); // Si el sistema operativo del server es
			 * windows, reemplazar los %20 por espacios para que no falle en la
			 * localizacion de los archivos if
			 * (System.getProperty("os.name").contains("Windows")){ control =
			 * control.replaceAll("%20", " "); } OutputStream output = new
			 * FileOutputStream(control);
			 */

			OutputStream output = new FileOutputStream(controlUrl.getPath());

			// Guardar la información codificada
			IOUtils.write(Base64.encodeBase64(new Long(licenseDate).toString().getBytes()), output);
			output.close();
		} catch (IOException e) {
			throw new ServiceException("File control.dat not found", e);
		}
	}
}